/**
 * File NegotiationMessageFactory.java created by Pablo Díaz Fernández
 * on 06/05/2012 for the project supply-chain-simulator
 */
package org.lsk.pfc.scsim.model.messages;

import jade.core.AID;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

import java.math.BigDecimal;

/**
 * Helper that deals with all the messages related to negotiation among agents.
 * 
 * @author Pablo Díaz Fernández
 */
public class NegotiationMessageFactory {
	/**
	 * Private constructor to avoid instantiation.
	 */
	protected NegotiationMessageFactory() {
	}

	/**
	 * Key for the user default slot amount.
	 */
	public static final String AMOUNT = "amount";

	/**
	 * Key for the user default slot price.
	 */
	public static final String PRICE = "price";

	/**
	 * Message template to match negotiation requests from client MAS.
	 */
	public static final MessageTemplate NEG_REQ_MSG_TEMPLATE = MessageTemplate
	        .and(MessageTemplate.MatchOntology(MessageFactory.NEG_ONTOLOGY),
	                MessageTemplate.MatchPerformative(ACLMessage.QUERY_REF));

	/**
	 * Message template to match negotiation responses from provider MAS.
	 */
	public static final MessageTemplate NEG_RES_MSG_TEMPLATE = MessageTemplate
	        .and(MessageTemplate.MatchOntology(MessageFactory.NEG_ONTOLOGY),
	                MessageTemplate.MatchPerformative(ACLMessage.QUERY_REF));

	/**
	 * Message template to match negotiation confirmation or cancelation from
	 * client MAS.
	 */
	public static final MessageTemplate NEG_PUR_MSG_TEMPLATE = MessageTemplate
	        .and(MessageTemplate.MatchOntology(MessageFactory.NEG_ONTOLOGY),
	                MessageTemplate.or(MessageTemplate
	                        .MatchPerformative(ACLMessage.AGREE),
	                        MessageTemplate
	                                .MatchPerformative(ACLMessage.REFUSE)));

	/**
	 * Creates a message to request for products in the current tick.
	 * 
	 * @param agentTarget
	 *            AID of the agent asked for info.
	 * @param agentSource
	 *            AID of the agent that asks for info.
	 * @param tickNo
	 *            Number of the current time tick.
	 * @param amount
	 *            Amount of product requested.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage getRequestProductMSG(final AID agentTarget,
	        final AID agentSource, final Long tickNo, final Integer amount) {
		ACLMessage msg = MessageFactory.getTickBasedMessage(agentTarget,
		        agentSource, MessageFactory.NEG_ONTOLOGY, ACLMessage.QUERY_REF,
		        tickNo, "");
		msg.addUserDefinedParameter(AMOUNT, amount.toString());
		return msg;
	}

	/**
	 * Creates a response message for a request for products in the current
	 * tick.
	 * 
	 * @param inResponseTo
	 *            {@link ACLMessage} origin.
	 * @param amount
	 *            Amount of product available.
	 * @param price
	 *            Price of the product.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage getResponseRequestProductMSG(
	        final ACLMessage inResponseTo, final Integer amount,
	        final BigDecimal price) {
		ACLMessage msg = new ACLMessage(ACLMessage.INFORM_REF);
		msg.addReceiver(inResponseTo.getSender());
		msg.setOntology(MessageFactory.NEG_ONTOLOGY);
		//msg.setContent("");
		msg.addUserDefinedParameter(AMOUNT, amount.toString());
		msg.addUserDefinedParameter(PRICE, price.toString());
		return msg;
	}

	/**
	 * Creates a message confirm a purchase.
	 * 
	 * @param inResponseTo
	 *            {@link ACLMessage} origin.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage getConfirmPurchaseMSG(
			final ACLMessage inResponseTo) {
		ACLMessage msg = new ACLMessage(ACLMessage.AGREE);
		msg.addReceiver(inResponseTo.getSender());
		msg.setOntology(MessageFactory.NEG_ONTOLOGY);
		// msg.setContent("");
		return msg;
	}

	/**
	 * Creates a message cancel a purchase.
	 * 
	 * @param inResponseTo
	 *            {@link ACLMessage} origin.
	 * @return {@link ACLMessage} Built.
	 */
	public ACLMessage getCancelPurchaseMSG(
			final ACLMessage inResponseTo) {
		ACLMessage msg = new ACLMessage(ACLMessage.REFUSE);
		msg.addReceiver(inResponseTo.getSender());
		msg.setOntology(MessageFactory.NEG_ONTOLOGY);
		// msg.setContent("");
		return msg;
	}
}
